package fuse.LaCollaFS;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Hashtable;

import LaColla.Api.Api;

import fuse.FuseException;
import fuse.LaCollaFS.Api.ApiImpl;
import fuse.LaCollaFS.Api.ApiServer;
import fuse.LaCollaFS.Metadades.MetaDades;

public class Organitzador {

	// private Hashtable<String, Vector<Long>> ModificantMetadades;
	// private long contador = 0;
	private Api api;

	private ApiServer aserv;

	private Operacions o;

	private int id = 0;

	private Paxos paxos;

	private void p(Object o) {
		System.out.println("Organitzador: " + o);
	}

	public Organitzador(Api api2, ApiServer aserv2, String apiid) {
		aserv = aserv2;
		api = api2;
		o = new Operacions();
		paxos = new Paxos(aserv, api, o);
		aserv.DefPaxos(paxos);

	}

	public int IniciarConsens(String path, String path2, String operacio)
			throws FuseException {
		String memberId = aserv.getMemberId();
		p("Operació a consensuar: " + operacio);
		id++;
		if (!paxos.TincLider()) {
			paxos.Any(id, memberId, "recovery");
		}

		Boolean negat;
		negat = true;

		paxos.IniAccept(id, "<Accept><path>" + path + "</path><op>" + operacio
				+ "</op><id>" + id + "</id><path2>" + path2
				+ "</path2></Accept>");

		boolean acabat = false;
		int i = 0;
		int j = 0;
		while (!acabat) {
			// p("valor de i :" + i + " i de j : " + j);
			i++;
			j++;
			if (j > 10) {

				throw new FuseException("Paxos no arribat!!!!")
						.initErrno(FuseException.EBUSY);

				// break;

			}
			if (i > 5) {
				if (id != paxos.Ultim()) {
					id = paxos.Ultim();
					paxos.IniAccept(id, "<Accept><path>" + path + "</path><op>"
							+ operacio + "</op><id>" + id + "</id><path2>"
							+ path2 + "</path2></Accept>");
				}
				i = 0;
			}
			acabat = Paxos.Finalitzat(id, path);
			// p("Organitzador: Acabat = "+acabat);

			if (!acabat) {
				// p("Organitzador: espero....");
				p("Operacions pendents: " + o.BuscarperPath(path));
				try {
					Thread.sleep(2000);
				} catch (Exception e) {
				}
			}
		}

		return id;
	}

	public void ObtenirStat(String path) {
		// no porta cap conflicte, procedim directament....

	}

	public int CanviarStat(String path) {

		String operacio = "CanviarStat";
		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int LlegirDir(String path) {
		String operacio = "LlegirDir";

		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int ModificarDir(String path) {
		String operacio = "CrearNode";

		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	/*
	 * public int EliminarDir(String path) { String operacio = "EliminarDir";
	 * 
	 * return IniciarConsens(path, null, operacio); }
	 */

	public int LlegirFitxer(String path) {
		String operacio = "LlegirFitxer";

	/*	int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}*/
		return 1;
	}

	public int EscriureFitxer(String path) {
		String operacio = "EscriureFitxer";

		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int EliminarFitxer(String path) {
		String operacio = "EliminarFitxer";

		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int MoureNode(String from, String to) {
		String operacio = "MoureNode";

		int i;
		try {
			i = IniciarConsens(from, to, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int CrearEnllas(String from, String to) {
		String operacio = "CrearEnllas";

		int i;
		try {
			i = IniciarConsens(from, to, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public int LlegirEnllas(String path) {
		String operacio = "LlegirEnllas";

		int i;
		try {
			i = IniciarConsens(path, null, operacio);
		} catch (Exception e) {
			i = -1;
		}
		return i;
	}

	public void Fet(int id) {
		o.TreureOperacio(id);
		ArrayList members = aserv.getMembers();
		String memberId = aserv.getMemberId();
		String groupId = "hola";

		try {
			api.sendInstantMessage(memberId, groupId, "<Fi>" + id + "</Fi>",
					members);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// /////////////////////////////////////////////////////////////////////////////777
	}

	public void FitxerDesat(String path) {
		ArrayList<ArrayList<Comparable>> llista = o.BuscarperPath(path);
		int i = -1;
		if (llista != null) {
			int j = 0;
			for (j = 0; j < llista.size(); j++) {
				ArrayList<Comparable> ll = llista.get(j);

				String s = (String) ll.get(1);
				if (s.equals("EscriureFitxer"))
					break;
				if (s.equals("LlegirFitxer"))
					break;

			}
			// p("Paxos: valir de j " + j + " llista " + llista.get(j).get(2));
			Comparable c = llista.get(j).get(2);
			String s = c.toString();
			i = Integer.valueOf(s);
		}
		this.Fet(i);
	}

}
